﻿using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Text;

namespace CN.T.Backend.Application.System.Utility
{
    /// <summary>
    /// 基于HttpClient封装的请求类
    /// </summary>
    public  class NetHttpHelp
    {
        private static HttpClient httpClient = new HttpClient();
        #region 同步
        /// <summary>
        /// Get方法请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <returns></returns>
        public static string GetQueryToString(string url, List<KeyValuePair<string, string>> headers = null)
        {
            HttpRequestMessage request = new HttpRequestMessage()
            {
                RequestUri = new Uri(url),
                Method = HttpMethod.Get,
            };
            if (headers != null && headers.Count > 0)
            {
                request.Headers.Clear();

                foreach (var header in headers)
                {
                    request.Headers.Add(header.Key, header.Value);

                }
            }
            HttpResponseMessage response = httpClient.SendAsync(request).Result;
            return response.Content.ReadAsStringAsync().Result;
        }

        /// <summary>
        /// Get方法请求并进行反序列化
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <returns></returns>
        public static T GetQueryToEntity<T>(string url, List<KeyValuePair<string, string>> headers = null)
        {
            return JsonConvert.DeserializeObject<T>(GetQueryToString(url, headers));
        }
        /// <summary>
        /// Post方法请求 application/x-www-form-urlencoded格式
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="paramList">参数集合</param>
        /// <returns></returns>
        public static string PostUrlEncodToString(string url, List<KeyValuePair<String, String>> paramList, List<KeyValuePair<string, string>> headers = null)
        {
            FormUrlEncodedContent formUrlEncodedContent = new FormUrlEncodedContent(paramList);
            if (headers != null && headers.Count > 0)
            {
                formUrlEncodedContent.Headers.Clear();
                foreach (var header in headers)
                {
                    formUrlEncodedContent.Headers.Add(header.Key, header.Value);
                }
            }
            HttpResponseMessage response = httpClient.PostAsync(new Uri(url), formUrlEncodedContent).Result;
            return response.Content.ReadAsStringAsync().Result;
        }

        public static T PostUrlEncodToEntity<T>(string url, List<KeyValuePair<String, String>> paramList, List<KeyValuePair<string, string>> headers = null)
        {
            return JsonConvert.DeserializeObject<T>(PostUrlEncodToString(url, paramList, headers));
        }
        /// <summary>
        /// Post方法请求 application/json格式
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="paramList">参数集合</param>
        /// <returns></returns>
        public static string PostJsonToString(string url, string content = "", List<KeyValuePair<string, string>> headers = null)
        {
            HttpContent FromContent = new StringContent(content, Encoding.UTF8);
            if (headers != null && headers.Count > 0)
            {
                FromContent.Headers.Clear();
                foreach (var header in headers)
                {
                    FromContent.Headers.Add(header.Key, header.Value);
                }
            }
            HttpResponseMessage response = httpClient.PostAsync(new Uri(url), FromContent).Result;
            return response.Content.ReadAsStringAsync().Result;
        }


        public static T PostJsonToEntity<T>(string url, string content = "", List<KeyValuePair<string, string>> headers = null)
        {
            return JsonConvert.DeserializeObject<T>(PostJsonToString(url, content, headers));
        }

        public static TResponse PostEntityToEntity<TRequest, TResponse>(string url, TRequest Entity, List<KeyValuePair<string, string>> headers = null)
        {
            return JsonConvert.DeserializeObject<TResponse>(PostJsonToString(url, JsonConvert.SerializeObject(Entity), headers));
        }
        #endregion

        #region 异步
        /// <summary>
        /// Get方法异步请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <returns></returns>
        public static async Task<string> GetQueryToStringAsync(string url, List<KeyValuePair<string, string>> headers = null)
        {
            HttpRequestMessage request = new HttpRequestMessage()
            {
                RequestUri = new Uri(url),
                Method = HttpMethod.Get,
            };
            if (headers != null && headers.Count > 0)
            {
                request.Headers.Clear();
                foreach (var header in headers)
                {
                    request.Headers.Add(header.Key, header.Value);
                }
            }
            return (await httpClient.SendAsync(request)).Content.ReadAsStringAsync().Result;
        }
        /// <summary>
        /// Get方法异步请求并进行实体序列化
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <returns></returns>
        public static async Task<T> GetQueryToEntityAsync<T>(string url, List<KeyValuePair<string, string>> headers = null)
        {
            return JsonConvert.DeserializeObject<T>((await GetQueryToStringAsync(url, headers)));
        }

        /// <summary>
        /// Post方法异步请求 application/x-www-form-urlencoded格式返回字符串
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="paramList">参数集合</param>
        /// <returns></returns>
        public static async Task<string> PostUrlEncodToStringAsync(string url, List<KeyValuePair<String, String>> paramList, List<KeyValuePair<string, string>> headers = null)
        {
            FormUrlEncodedContent formUrlEncodedContent = new FormUrlEncodedContent(paramList);
            if (headers != null && headers.Count > 0)
            {
                formUrlEncodedContent.Headers.Clear();
                foreach (var header in headers)
                {
                    formUrlEncodedContent.Headers.Add(header.Key, header.Value);
                }
            }
            return (await httpClient.PostAsync(new Uri(url), formUrlEncodedContent)).Content.ReadAsStringAsync().Result;
        }
        /// <summary>
        /// Post方法异步请求 application/x-www-form-urlencoded格式并进行泛型实体类序列化
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="paramList">参数集合</param>
        /// <returns></returns>
        public static async Task<T> PostUrlEncodToEntityAsync<T>(string url, List<KeyValuePair<String, String>> paramList, List<KeyValuePair<string, string>> headers = null)
        {
            return JsonConvert.DeserializeObject<T>(await PostUrlEncodToStringAsync(url, paramList, headers));
        }

        /// <summary>
        /// Post方法异步请求 application/json格式返回字符串
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="content">raw data</param>
        /// <returns></returns>
        public static async Task<string> PostJsonToStringAsync(string url, string content = "", List<KeyValuePair<string, string>> headers = null)
        {
            StringContent stringContent = new StringContent(content, Encoding.UTF8);
            if (headers != null && headers.Count > 0)
            {
                stringContent.Headers.Clear();
                foreach (var header in headers)
                {
                    stringContent.Headers.Add(header.Key, header.Value);
                }
            }
            return (await httpClient.PostAsync(new Uri(url), stringContent)).Content.ReadAsStringAsync().Result;
        }

        /// <summary>
        /// Post方法异步请求 application/json格式返回字符串
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="content">raw data</param>
        /// <returns></returns>
        public static async Task<string> PostJsonToStringWeAsync(string url, string content = "", List<KeyValuePair<string, string>> headers = null)
        {
            StringContent stringContent = new StringContent(content, Encoding.UTF8);
            //stringContent.Headers.Add("Accept", "application/json");
            //stringContent.Headers.Add("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50");
            return (await httpClient.PostAsync(new Uri(url), stringContent)).Content.ReadAsStringAsync().Result;
        }

        /// <summary>
        /// Post方法异步使用泛型实体类参数请求 application/json格式返回Byte[]
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <param name="Entity"></param>
        /// <param name="headers"></param>
        /// <returns></returns>
        public static async Task<Byte[]> PostEntityToBufferAsync<T>(string url, T Entity, List<KeyValuePair<string, string>> headers = null)
        {
            StringContent stringContent = new StringContent(JsonConvert.SerializeObject(Entity), Encoding.UTF8);
            if (headers != null && headers.Count > 0)
            {
                stringContent.Headers.Clear();
                foreach (var header in headers)
                {
                    stringContent.Headers.Add(header.Key, header.Value);
                }
            }
            return (await httpClient.PostAsync(new Uri(url), stringContent)).Content.ReadAsByteArrayAsync().Result;
        }
        /// <summary>
        /// Post方法异步请求 application/json格式对泛型类进行反序列化
        /// </summary>
        /// <returns></returns>
        public static async Task<T> PostJsonToEntityAsync<T>(string url, string content = "", List<KeyValuePair<string, string>> headers = null)
        {
            return JsonConvert.DeserializeObject<T>(await PostJsonToStringAsync(url, content, headers));
        }
        /// <summary>
        /// Post方法异步请求 application/json格式
        /// TRequest为请求参数、TResponse为返回参数
        /// </summary>
        /// <returns></returns>
        public static async Task<TResponse> PostEntityToEntityAsync<TRequest, TResponse>(string url, TRequest Entity, List<KeyValuePair<string, string>> headers = null)
        {
            return JsonConvert.DeserializeObject<TResponse>(await PostJsonToStringAsync(url, JsonConvert.SerializeObject(Entity), headers));
        }

        /// <summary>
        /// 向目标地址提交图片文件参数数据 multipart/form-data内容类型
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="bmpBytes">图片字节流</param>
        /// <param name="imgType">上传图片类型文件格式，拓展名</param>
        /// <param name="fileName">图片名称</param>
        /// <param name="parameterName">与第三方接口的参数名保持一致</param>
        /// <returns></returns>
        public static async Task<string> PostFormDataToStringAsync(string url, byte[] bmpBytes, string imgType, string fileName, string parameterName)
        {
            List<ByteArrayContent> byteArrayContents = new List<ByteArrayContent>();

            var imgTypeContent = new ByteArrayContent(Encoding.UTF8.GetBytes(imgType));
            imgTypeContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name = "imgType"
            };
            byteArrayContents.Add(imgTypeContent);

            var fileContent = new ByteArrayContent(bmpBytes);//填充图片文件二进制字节
            fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name = parameterName,
                FileName = fileName
            };
            byteArrayContents.Add(fileContent);

            var content = new MultipartFormDataContent();
            //将ByteArrayContent集合加入到MultipartFormDataContent中
            foreach (var byteArrayContent in byteArrayContents)
            {
                content.Add(byteArrayContent);
            }
            try
            {
                var result = await httpClient.PostAsync(url, content);//post请求
                return result.Content.ReadAsStringAsync().Result;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        #endregion





        /// <summary>
        /// 释放httpclient
        /// </summary>
        public void Release()
        {
            httpClient.Dispose();
        }
    }

}
